Erstellt:10.02.2014
Aktualisiert:10.02.2014

ATmega UART Bootloader

Manchmal kann es praktisch sein einen Bootloader zu verwenden, z.B. wenn die Platine so gut verpackt ist, dass man nicht mehr richtig mit einem Programmierstecker dran kommt. Hat man bereits eine USB-Buchse und FT232 vorgesehen, kann man das Gerät über diese auch gleich mit neuer Firmware versorgen.

Der hier vorgestellte Bootloader ist so ausgelegt, dass er nur minimalen Platz belegt. Die Bootloadersektion kann nur in bestimmten Schritten vergrößert werden. Dieser Bootloader hat eine Größe von knapp unter 1024 Byte. Die nächst größere Bootloader Sektion wäre schon 2048 Byte groß. Die Beschreibung bezieht sich auf einen ATmega168P.

Ein gute Beschreibung der Grundlagen gibt es bei mikrocontroller.net. Wer wissen möchte wie ein von Compiler erzeugtes HEX-File aussieht sollte sich diesen Artikel durchlesen: Wikipedia: Intel HEX

 

Bootloader Beispielprojekt und Programmiertool für Windows:

Bootloader.rar

 

Der Bootloader wird ans Ende des Speichers geschrieben. Deswegen müssen wir im AtmelStudio unter Projekt->Toolchain->AVR/GNU Linker->Miscellaneous mit -Ttext=0x3C00 die Adresse angeben wo der Bootloader hingeschrieben werden soll. Vor dem Programmieren müssen noch die Fuse-Bits richtig gesetzt werden. Für diesen Bootloader müssen BOOTSZ1=0 und BOTSZ0=1 gesetzt werden. Somit stehen 1024 Byte Speicher für unseren Bootloader ab Adresse 0x3C00 zur Verfügung. Ist der Bootloader auf den AVR geschrieben kann auch schon benutzt werden um die erste Anwendung auf den Mikrocontroller zu schreiben. Die Ausführung des Programmspeichers beginnt zwar ab der Adresse 0, allerdings wird der Programmcounter bei jedem Takt hochgezählt bis er bei dem Bootloader angekommen ist.

Der Bootloader wird aus der Applikation heraus gestartet indem einer Funktion eine Speicheradresse zugewiesen wird, an der die Ausführung fortgesetzt wird. Es muss unbedingt darauf geachtet werden, dass vorher die Interrupts deaktiviert werden. Ein Nachteil dabei ist, dass ein Fehler beim Programmieren der Applikation einen erneuten Start des Bootloaders unmöglich machen kann. In diesem Fall muss der AVR mit einem Programmiergerät neu beschrieben werden.

void (*bootloader)( void ) = 0x1E00; // Achtung Falle: Hier Word-Adresse

Ein anderer Weg ist, die Boot Reset Adresse mit dem Fuse-Bit BOOTRST direkt auf den Bootloader zu programmieren. Dann beginnt die Programmausführung immer mit dem Bootloader. In diesem Fall kann z.B. am Beginn des Bootloadercode ein Pin auf einen bestimmten Zustand abgefragt werden. Je nach Zustand wird die Anwendung gestartet oder der Bootloader fortgesetzt. So kann immer eine neue Applikation aufgespielt werden, auch wenn diese fehlerhaft ist.

if(PIND & (1<<PIND2)) { startProgram(); }

Der Bootloader funktioniert nach folgenden Ablauf:

  1. PC sendet eine Zeile der HEX-Datei
  2. PC wartet auf ein Acknowledge (0xAC) oder Checksum Error (0xEC)
  3. Wenn ACK empfangen nächste Zeile senden (Punkt 1 wiederholen)

Ein kleines Programm kann auch zeilenweise "per Hand" mit einem Terminalprogramm übertragen werden.

Ein andere Lösung wäre eine Flow-Control, die aber mehr Programmspeicher erfordert. Eine software Flow-Control kann auch zu Problemen führen wenn sie nicht schnell genug verarbeitet wird.